package com.cnap.controller;

import com.cnap.model.common.CommonResult;
import com.cnap.model.common.PageResult;
import com.cnap.model.intelligent.UpdateIntelligentDTO;
import com.cnap.model.log.OperationTypeEnum;
import com.cnap.model.schedule.OperateTypeEnum;
import com.cnap.model.schedule.QueryMicroServiceParam;
import com.cnap.model.schedule.UpdateUserChooseParam;
import com.cnap.model.strategy.MicroServiceVOV2;
import com.cnap.model.strategy.OperateParamV2;
import com.cnap.model.strategy.StrategyVO;
import com.cnap.model.strategy.scale.ScaleStrategyDTO;
import com.cnap.model.strategy.schedule.ScheduleStrategyDTO;
import com.cnap.service.OperateService;
import com.cnap.service.OperationLogService;
import com.cnap.service.StrategyService;
import com.cnap.utils.JsonUtil;
import com.cnap.utils.TokenUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 策略控制类
 *
 * @author xc
 **/
@Api(tags = "策略部署-策略管理")
@RestController
@RequestMapping("/api/strategy")
public class ScheduleController {

    private static final Logger LOGGER = LoggerFactory.getLogger(ScheduleController.class);

    private final StrategyService strategyService;
    private final OperationLogService operationLogService;
    private final OperateService operateService;

    @Autowired
    public ScheduleController(StrategyService strategyService, OperationLogService operationLogService, OperateService operateService) {
        this.strategyService = strategyService;
        this.operationLogService = operationLogService;
        this.operateService = operateService;
    }

    /**
     * 添加调度策略
     *
     * @param scheduleStrategyDTOs 策略信息
     * @return 结果
     */
    @ApiOperation(value = "添加调度策略", notes = "添加调度策略", httpMethod = "POST")
    @PostMapping("/schedule/add")
    public CommonResult<String> addScheduleStrategy(@RequestBody List<ScheduleStrategyDTO> scheduleStrategyDTOs) {
        LOGGER.info("[strategy]: add schedule strategy={}", JsonUtil.objectToJsonStr(scheduleStrategyDTOs));
        strategyService.addScheduleStrategy(scheduleStrategyDTOs);
        String message = TokenUtils.getUserName() + "添加了调度策略";
        operationLogService.saveOperationLog(OperationTypeEnum.ADD.getType(), message);
        return CommonResult.success("success");
    }

    /**
     * 添加调度策略
     *
     * @param scaleStrategyDTOS 策略信息
     * @return 结果
     */
    @ApiOperation(value = "添加扩缩容策略", notes = "添加扩缩容策略", httpMethod = "POST")
    @PostMapping("/scale/add")
    public CommonResult<String> addScaleStrategy(@RequestBody List<ScaleStrategyDTO> scaleStrategyDTOS) {
        LOGGER.info("[strategy]: add scale strategy={}", JsonUtil.objectToJsonStr(scaleStrategyDTOS));
        strategyService.addScaleStrategy(scaleStrategyDTOS);
        String message = TokenUtils.getUserName() + "添加了扩缩容策略";
        operationLogService.saveOperationLog(OperationTypeEnum.ADD.getType(), message);
        return CommonResult.success("success");
    }


    @ApiOperation(value = "根据应用id查询微服务策略")
    @GetMapping("/list/{appId}")
    public CommonResult<List<StrategyVO>> getStrategyByAppId(@PathVariable("appId") String appId) {
        List<StrategyVO> results = strategyService.getStrategyByAppId(appId);

        return CommonResult.success(results);
    }

    /**
     * 根据id列表删除调度策略
     *
     * @param strategyIds 策略id列表
     * @return 结果
     */
    @ApiOperation(value = "删除调度策略", notes = "删除调度策略", httpMethod = "POST")
    @PostMapping("/schedule/delete")
    public CommonResult<String> deleteScheduleStrategyByIds(@RequestBody List<String> strategyIds) {
        LOGGER.info("[strategy]: delete schedule strategy ids={}", strategyIds);
        boolean result = strategyService.deleteScheduleStrategy(strategyIds);

        String message = TokenUtils.getUserName() + "删除了调度策略";
        operationLogService.saveOperationLog(OperationTypeEnum.DELETE.getType(), message);
        return result ? CommonResult.success("success") : CommonResult.failed("fail");
    }

    /**
     * 根据id列表删除调度策略
     *
     * @param strategyIds 策略id列表
     * @return 结果
     */
    @ApiOperation(value = "删除扩缩容策略", notes = "删除扩缩容策略", httpMethod = "POST")
    @PostMapping("/scale/delete")
    public CommonResult<String> deleteScaleStrategyByIds(@RequestBody List<String> strategyIds) {
        LOGGER.info("[strategy]: delete scale strategy ids={}", strategyIds);
        boolean result = strategyService.deleteScaleStrategy(strategyIds);

        String message = TokenUtils.getUserName() + "删除了扩缩容策略";
        operationLogService.saveOperationLog(OperationTypeEnum.DELETE.getType(), message);
        return result ? CommonResult.success("success") : CommonResult.failed("fail");
    }

    @ApiOperation(value = "更新用户选择", notes = "更新用户选择", httpMethod = "POST")
    @PostMapping("/update/user-choose")
    public CommonResult<String> updateUserChooseCloudV2(@RequestBody UpdateUserChooseParam updateUserChooseParam) {
        LOGGER.info("[strategy]: update user choose cloud, {}", updateUserChooseParam);
        strategyService.updateUserChoose(updateUserChooseParam);
        return CommonResult.success("success");
    }

    /**
     * 策略部署-查询微服务
     *
     * @param queryMicroServiceParam 查询参数
     * @return 结果
     */
    @ApiOperation(value = "查询微服务", notes = "查询微服务", httpMethod = "POST")
    @PostMapping("/list/svc")
    public CommonResult<PageResult<MicroServiceVOV2>> listMicroServiceV2(@RequestBody QueryMicroServiceParam queryMicroServiceParam) {
        PageResult<MicroServiceVOV2> result = strategyService.findByPage(queryMicroServiceParam);
        return CommonResult.success(result);
    }

    /**
     * 操作（暂停，恢复）
     *
     * @param operateParam 操作参数
     * @return 结果
     */
    @ApiOperation(value = "操作", notes = "操作", httpMethod = "POST")
    @PostMapping("/operation")
    public CommonResult<String> operationV2(@Validated @RequestBody OperateParamV2 operateParam) {
        LOGGER.info("[strategy]: operate service, {}", operateParam);
        boolean result = operateService.operateV2(operateParam);

        String message = TokenUtils.getUserName() + OperateTypeEnum.getOperateTypeFromType(operateParam.getOperationType())
                .getMessage() + "了微服务";
        if (OperateTypeEnum.DELETE.getMessage().equals(operateParam.getOperationType())) {
            operationLogService.saveOperationLog(OperationTypeEnum.DELETE.getType(), message);
        } else {
            operationLogService.saveOperationLog(OperationTypeEnum.OTHER.getType(), message);
        }

        return result ? CommonResult.success("success") : CommonResult.failed("fail");
    }

    /**
     * 更新智能调度策略
     *
     * @return 结果
     */
    @ApiOperation(value = "更新智能调度策略", notes = "更新智能调度策略", httpMethod = "POST")
    @PostMapping("/intelligent/update")
    public CommonResult<String> updateIntelligent(@RequestBody UpdateIntelligentDTO updateIntelligentDTO) {
        strategyService.updateIntelligentParam(updateIntelligentDTO);
        return CommonResult.success("success");
    }

    @ApiOperation(value = "根据id删除智能决策记录", notes = "根据id删除智能决策记录", httpMethod = "DELETE")
    @DeleteMapping("/intelligent/delete/{id}")
    public CommonResult<String> deleteIntelligentHistoryById(@PathVariable("id") String id) {
        strategyService.deleteIntelligentHistoryById(id);
        return CommonResult.success("success");
    }

}
